#include "StdAfx.h"



COpenGLControl::COpenGLControl(void)
{
	m_fPosX = 0.0f;		// X position of model in camera view
	m_fPosY = 0.0f;		// Y position of model in camera view
	m_fZoom = 10.0f;	// Zoom on model in camera view
	m_fRotX = 0.0f;		// Rotation on model in camera view
	m_fRotY	= 0.0f;		// Rotation on model in camera view
	m_bIsMaximized = false;
}

COpenGLControl::~COpenGLControl(void)
{

}

BEGIN_MESSAGE_MAP(COpenGLControl, CWnd)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_MOUSEMOVE()
END_MESSAGE_MAP()

void COpenGLControl::OnPaint()
{
	//CPaintDC dc(this); // device context for painting
	ValidateRect(NULL);
}
void COpenGLControl::OnSize(UINT nType, int cx, int cy)
{
	CWnd::OnSize(nType, cx, cy);

	if (0 >= cx || 0 >= cy || nType == SIZE_MINIMIZED) return;

	// Map the OpenGL coordinates.
	globals.Graphics.Resize(cx, cy);
	switch (nType)
	{
		// If window resize token is "maximize"
		case SIZE_MAXIMIZED:
		{
			// Get the current window rect
			GetWindowRect(m_rect);

			// Move the window accordingly
			MoveWindow(6, 6, cx - 14, cy - 14);

			// Get the new window rect
			GetWindowRect(m_rect);

			// Store our old window as the new rect
			m_oldWindow = m_rect;

			break;
		}

		// If window resize token is "restore"
		case SIZE_RESTORED:
		{
			// If the window is currently maximized
			if (m_bIsMaximized)
			{
				// Get the current window rect
				GetWindowRect(m_rect);

				// Move the window accordingly (to our stored old window)
				MoveWindow(m_oldWindow.left, m_oldWindow.top - 18, m_originalRect.Width() - 4, m_originalRect.Height() - 4);

				// Get the new window rect
				GetWindowRect(m_rect);

				// Store our old window as the new rect
				m_oldWindow = m_rect;
			}
		
			break;
		}
	}
}

int COpenGLControl::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1) return -1;

	oglInitialize();

	return 0;
}

void COpenGLControl::OnDraw(CDC *pDC)
{
}

void COpenGLControl::OnTimer(UINT nIDEvent)
{
	static double lastTick=GetTickCount();
	double thisTick=GetTickCount(), d=thisTick-lastTick;
	if(d>1000/60)
	{
		lastTick=thisTick;
		globals.Game.Update(d/1000);
		switch (nIDEvent)
		{
			case 1:
			{
				// Draw OpenGL scene
				oglDrawScene();
				break;
			}
			default:
				break;
		}
	}
	CWnd::OnTimer(nIDEvent);
}

void COpenGLControl::OnMouseMove(UINT nFlags, CPoint point)
{
	try
	{
		globals.Input.ProcessMousePress(nFlags);
		globals.Input.ProcessMouseMove(Vec3(point.x, point.y, 0));
		OnDraw(NULL);

		CWnd::OnMouseMove(nFlags, point);
	}
	catch(std::exception e)
	{
		alert(string("Uncaught input exception detected: ")<<e.what());
	}
}

void COpenGLControl::oglCreate(CRect rect, CWnd *parent)
{
	CString className = AfxRegisterWndClass(CS_HREDRAW | CS_VREDRAW | CS_OWNDC, NULL, (HBRUSH)GetStockObject(BLACK_BRUSH), NULL);

	CreateEx(0, className, L"OpenGL", WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN, rect, parent, 0);

	// Set initial variables' values
	m_oldWindow	   = rect;
	m_originalRect = rect;

	hWnd = parent;
}

void COpenGLControl::oglInitialize(void)
{
	try
	{
		hdc=GetDC()->m_hDC;
		globals.Init(hdc);
		// Send draw request
		OnDraw(NULL);
	}
	catch(std::exception e)
	{
		alert(string("Uncaught init exception detected: ")<<e.what());
	}
}

void COpenGLControl::oglDrawScene(void)
{
	try
	{
		globals.Graphics.Render();
		SwapBuffers(hdc);
	}
	catch(std::exception e)
	{
		alert(string("Uncaught render exception detected: ")<<e.what());
	}
}